From 20611cf68c6a95765bd0c1a87f8e66423ee56f9f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 4 Jun 2020 21:33:44 -0400 Subject: [PATCH] Add gtk_selection_model_[un]select_callback Add a methods to add or remove a whole set (specified via a query-range style callback). --- gtk/gtkmultiselection.c | 57 +++++++++++++++++++++++++++++++++++++++++ gtk/gtkselectionmodel.c | 54 ++++++++++++++++++++++++++++++++------ gtk/gtkselectionmodel.h | 23 ++++++++++++++++- 3 files changed, 125 insertions(+), 9 deletions(-) diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c index f8ed44c2d4..a0ffb92fee 100644 --- a/gtk/gtkmultiselection.c +++ b/gtk/gtkmultiselection.c @@ -167,6 +167,61 @@ gtk_multi_selection_unselect_all (GtkSelectionModel *model) return gtk_multi_selection_unselect_range (model, 0, g_list_model_get_n_items (G_LIST_MODEL (model))); } +static gboolean +gtk_multi_selection_add_or_remove (GtkSelectionModel *model, + gboolean add, + GtkSelectionCallback callback, + gpointer data) +{ + GtkMultiSelection *self = GTK_MULTI_SELECTION (model); + guint pos, start, n; + gboolean in; + guint min, max; + + min = G_MAXUINT; + max = 0; + + pos = 0; + do + { + callback (pos, &start, &n, &in, data); + if (in) + { + if (start < min) + min = start; + if (start + n - 1 > max) + max = start + n - 1; + + if (add) + gtk_set_add_range (self->selected, start, n); + else + gtk_set_remove_range (self->selected, start, n); + } + pos = start + n; + } + while (n > 0); + + gtk_selection_model_selection_changed (model, min, max - min + 1); + + return TRUE; +} + +static gboolean +gtk_multi_selection_select_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + return gtk_multi_selection_add_or_remove (model, TRUE, callback, data); +} + +static gboolean +gtk_multi_selection_unselect_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + return gtk_multi_selection_add_or_remove (model, FALSE, callback, data); +} + static void gtk_multi_selection_query_range (GtkSelectionModel *model, guint position, @@ -190,6 +245,8 @@ gtk_multi_selection_selection_model_init (GtkSelectionModelInterface *iface) iface->unselect_range = gtk_multi_selection_unselect_range; iface->select_all = gtk_multi_selection_select_all; iface->unselect_all = gtk_multi_selection_unselect_all; + iface->select_callback = gtk_multi_selection_select_callback; + iface->unselect_callback = gtk_multi_selection_unselect_callback; iface->query_range = gtk_multi_selection_query_range; } diff --git a/gtk/gtkselectionmodel.c b/gtk/gtkselectionmodel.c index 8053368c6b..dfbf167f9a 100644 --- a/gtk/gtkselectionmodel.c +++ b/gtk/gtkselectionmodel.c @@ -113,6 +113,22 @@ gtk_selection_model_default_unselect_range (GtkSelectionModel *model, return FALSE; } +static gboolean +gtk_selection_model_default_select_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + return FALSE; +} + +static gboolean +gtk_selection_model_default_unselect_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + return FALSE; +} + static gboolean gtk_selection_model_default_select_all (GtkSelectionModel *model) { @@ -142,20 +158,22 @@ gtk_selection_model_default_query_range (GtkSelectionModel *model, else { *n_items = 1; - *selected = gtk_selection_model_is_selected (model, position); + *selected = gtk_selection_model_is_selected (model, position); } } static void gtk_selection_model_default_init (GtkSelectionModelInterface *iface) { - iface->is_selected = gtk_selection_model_default_is_selected; - iface->select_item = gtk_selection_model_default_select_item; - iface->unselect_item = gtk_selection_model_default_unselect_item; - iface->select_range = gtk_selection_model_default_select_range; - iface->unselect_range = gtk_selection_model_default_unselect_range; - iface->select_all = gtk_selection_model_default_select_all; - iface->unselect_all = gtk_selection_model_default_unselect_all; + iface->is_selected = gtk_selection_model_default_is_selected; + iface->select_item = gtk_selection_model_default_select_item; + iface->unselect_item = gtk_selection_model_default_unselect_item; + iface->select_range = gtk_selection_model_default_select_range; + iface->unselect_range = gtk_selection_model_default_unselect_range; + iface->select_all = gtk_selection_model_default_select_all; + iface->unselect_all = gtk_selection_model_default_unselect_all; + iface->select_callback = gtk_selection_model_default_select_callback; + iface->unselect_callback = gtk_selection_model_default_unselect_callback; iface->query_range = gtk_selection_model_default_query_range; /** @@ -324,6 +342,26 @@ gtk_selection_model_unselect_all (GtkSelectionModel *model) return iface->unselect_all (model); } +gboolean +gtk_selection_model_select_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE); + + return GTK_SELECTION_MODEL_GET_IFACE (model)->select_callback (model, callback, data); +} + +gboolean +gtk_selection_model_unselect_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data) +{ + g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE); + + return GTK_SELECTION_MODEL_GET_IFACE (model)->unselect_callback (model, callback, data); +} + /** * gtk_selection_model_query_range: * @model: a #GtkSelectionModel diff --git a/gtk/gtkselectionmodel.h b/gtk/gtkselectionmodel.h index 9e8de6a66b..3a73572ac2 100644 --- a/gtk/gtkselectionmodel.h +++ b/gtk/gtkselectionmodel.h @@ -29,10 +29,17 @@ G_BEGIN_DECLS #define GTK_TYPE_SELECTION_MODEL (gtk_selection_model_get_type ()) - + GDK_AVAILABLE_IN_ALL G_DECLARE_INTERFACE (GtkSelectionModel, gtk_selection_model, GTK, SELECTION_MODEL, GListModel) +typedef void (* GtkSelectionCallback) (guint position, + guint *start_range, + guint *n_items, + gboolean *selected, + gpointer data); + + /** * GtkSelectionModelInterface: * @is_selected: Return if the item at the given position is selected. @@ -79,6 +86,12 @@ struct _GtkSelectionModelInterface guint n_items); gboolean (* select_all) (GtkSelectionModel *model); gboolean (* unselect_all) (GtkSelectionModel *model); + gboolean (* select_callback) (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data); + gboolean (* unselect_callback) (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data); void (* query_range) (GtkSelectionModel *model, guint position, guint *start_range, @@ -111,6 +124,14 @@ gboolean gtk_selection_model_select_all (GtkSelectionMod GDK_AVAILABLE_IN_ALL gboolean gtk_selection_model_unselect_all (GtkSelectionModel *model); +GDK_AVAILABLE_IN_ALL +gboolean gtk_selection_model_select_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data); +gboolean gtk_selection_model_unselect_callback (GtkSelectionModel *model, + GtkSelectionCallback callback, + gpointer data); + GDK_AVAILABLE_IN_ALL void gtk_selection_model_query_range (GtkSelectionModel *model, guint position, -- 2.30.2